<?php

class Controller_Action extends Zend_Controller_Action
{
	const AJAX_STATUS_OK = 'OK';
	const AJAX_STATUS_ERROR = 'ERROR';
	const AJAX_STATUS_FATAL = 'FATAL';

	/** @var UserRow */
	protected $_user = null;
	
	/** @var GroupsRow */
	protected $_group = null;
	
	/** @var TurnRow */
	protected $_turn = null;
	

	public function preDispatch()
	{
		$user = $this->getUser();
		if (!$user) {
			$this->_redirect('/auth');
			return;
		}
		
		if (!$user->getAccessToken()) {
			$this->_redirect('/auth/accept');
			return;
		}
		
		if (!$groups = $user->getGroupsRowsetByUser2group()) {
			$this->_redirect('/auth/get.groups');
			return;
		}
		
		$this->view->request = $this->_getAllParams();
		$this->view->user = $user;
		$this->view->groups = $groups;
		
		parent::preDispatch();
	}

	/**
	 * Возвращаем объект пользователя.
	 *
	 * @return UserRow
	 * @throws Zend_Auth_Exception
	 */
	public function getUser()
	{
		return Auth::getInstance()->getProfile();
	}

	/**
	 * Возвращает запись группы из базы по ID в запросе.
	 *
	 * @return GroupsRow
	 */
	protected function _getGroupRow()
	{
		if ($this->_group instanceof GroupsRow) {
			return $this->_group;
		}
		
		if (!$id = $this->_getParam("group_id")) {
			throw new Zend_Navigation_Exception('Group id undefined');
		}
	
		$groupRow = GroupsPeer::getInstance()->find($id)->current();
		if (!$groupRow) {
			throw new Zend_Navigation_Exception('Group not found: ' . $id);
		}
	
		$this->_group = $groupRow;
		return $groupRow;
	}
	
	/**
	 * Возвращает запись очереди из базы по ID в запросе.
	 *
	 * @return TurnRow
	 */
	protected function _getTurnRow()
	{
		if ($this->_turn instanceof TurnRow) {
			return $this->_turn;
		}
		
		if (!$id = $this->_getParam("turn_id")) {
			throw new Zend_Navigation_Exception('Turn id undefined');
		}
	
		$turnRow = TurnPeer::getInstance()->find($id)->current();
		if (!$turnRow) {
			throw new Zend_Navigation_Exception('Turn not found: ' . $id);
		}
	
		$this->_turn = $turnRow;
		return $turnRow;
	}
	
	/**
	 * Return Layout helper.
	 *
	 * @return Zend_Layout_Controller_Plugin_Layout
	 */
	protected function _getLayout()
	{
		return $this->getHelper('layout');
	}

	/**
	 * Wrap for Zend_Controller_Router_Rewrite::assemble
	 * Generates an url given the name of a route.
	 *
	 * @access public
	 *        
	 * @param array $urlOptions
	 *        	Options passed to the assemble method of the Route object.
	 * @param mixed $name
	 *        	The name of a Route to use. If null it will use the current
	 *        	Route
	 * @param bool $reset
	 *        	Whether or not to reset the route defaults with those provided
	 * @return string Url for the link href attribute.
	 */
	public function getUrl(array $urlOptions = array(), $name = null, $reset = false, $encode = true)
	{
		$router = $this->getFrontController()->getRouter();
		return $router->assemble($urlOptions, $name, $reset, $encode);
	}

	/**
	 * Disable layout and viewRenderer plugin.
	 *
	 * @return void
	 */
	protected function _disableView()
	{
		$this->_helper->layout()->disableLayout();
		$this->getFrontController()->setParam('noViewRenderer', true);
	}

	protected function _disableLayout()
	{
		$this->_helper->layout()->disableLayout();
	}

	/**
	 * Отключает вывод всех отладочных данных
	 * 
	 * @return void
	 */
	public function hideDebug()
	{
		Debug::getInstance()->hideDebug();
	}

	/**
	 * Set JSON data to response body
	 *
	 * @param array $data        	
	 * @return void
	 */
	protected function _setJson($data)
	{
		$this->_disableView();
		if (! is_array($data)) {
			$data = array(
					$data
			);
		}
		$this->getResponse()->setBody(Zend_Json::encode($data));
	}

	protected function _setResponce($text)
	{
		$this->_disableView();
		$this->getResponse()->setBody($text);
	}

	/**
	 * передача данных для ajax ответа
	 *
	 * @param array|string $body тело ответа
	 * @param string $status статус обработки
	 * @param array $errors массив ошибок выполнения
	 * @return void
	 */
	protected function _setAjaxResponse($body, $status = self::AJAX_STATUS_OK, $messages = array())
	{
		$result = array(
				'status' => $status,
				'body' => $body
		);
		
		if (! empty($messages)) {
			$result['messages'] = $messages;
		}
		$this->_setJson($result);
	}

	/**
	 * Throw exception for non ajax calls
	 *
	 * @return void
	 * @throws Exception
	 */
	protected function _ajaxOnly()
	{
		if (! Debug::getInstance()->isDebugMode() &&
				 ! $this->getRequest()->isXmlHttpRequest()) {
			throw new Exception('This is AJAX-only action');
		}
		
		$this->_helper->layout()->disableLayout();
	}

	/**
	 * Redirect to a route-based URL
	 *
	 * Uses route's assemble method tobuild the URL; route is specified by
	 * $name;
	 * default route is used if none provided.
	 *
	 * @param array $urlOptions
	 *        	Array of key/value pairs used to assemble URL
	 * @param string $name        	
	 * @param boolean $reset        	
	 */
	protected function _goto(array $urlOptions = array(), $name = null, $reset = false)
	{
		$this->_helper->redirector->gotoRoute($urlOptions, $name, $reset);
	}

	protected function _getActionParams()
	{
		$params = $this->_getAllParams();
		unset($params['controller']);
		unset($params['action']);
		unset($params['module']);
		
		return $params;
	}

	protected function _checkAllowableParams($params)
	{
		$actionParams = array_keys($this->_getActionParams());
		
		return array_diff($actionParams, $params);
	}
}
